﻿using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;

/// <summary>
/// Summary description for ProyectosCtrl
/// </summary>
public class ProyectosCtrl
{
    private ProyectosBD bdProyectos;
    private static ProyectoEnt entProyectos;
    private AtributosCtrl atributos;
    private EmpleadosCtrl ctrlEmpleados;
    private ClientesCtrl ctrlClientes;
    private EstructuracionCtrl ctrlEstructuracion;

    private static List<EmpleadosEnt> listEmpleados = new List<EmpleadosEnt>();
    private static List<ClientesEnt> listClientes = new List<ClientesEnt>();
    private static List<IteracionEnt> listIteraciones = new List<IteracionEnt>();
    private static object listEmpleadosAsignados = new List<EmpleadosEnt>();
    private EstructuracionBD bdEstructuracion = new EstructuracionBD();
    private static object listEmpleadosPosibles  = new List<EmpleadosEnt>();
     
    public ProyectosCtrl() {
        this.bdProyectos = new ProyectosBD();
        this.atributos = new AtributosCtrl();
        this.ctrlClientes = new ClientesCtrl();
        this.ctrlEmpleados = new EmpleadosCtrl();
    }

    public List<ProyectoEnt> CargarProyectos()
    {
        return this.bdProyectos.RecuperarProyectos();
    }

    //Obtiene y retorna un dataTable con la informacion de proyectos
    public DataTable ActualizarGrid()
    {
        return this.bdProyectos.ConsultarProyectos();
    }

    //Recibe el id de un proyecto y consulta el proyecto con ese id almacenando los datos
    //en un objeto entidad y retorna ese objeto con la informacion del proyecto consultado
    public ProyectoEnt ConsultarProyecto(int id) 
    {
        entProyectos = this.bdProyectos.ConsultarProyecto(id);
        return entProyectos;
    }


    //Se llama al metodo eliminar de la controladora base de datos enviando como parametro
    //el id del ultimo proyecto consultado. Retorna true si se realizo la eliminacion con exito 
    //y false en caso contrario
    public bool EliminarProyecto()
    {
        return this.bdProyectos.EliminarProyecto(entProyectos.Id);
    }

    
    //Retorna un DataTable que contiene los atributos de nombre y cédula de los empleados.
    public List<EmpleadosEnt> ObtenerEmpleados()
    {
        listEmpleados = this.ctrlEmpleados.ConsultarEmpleadosLideres();
        listEmpleadosPosibles = ctrlEmpleados.ConsultarEmpleadosDisponibles();
        return listEmpleados;
    }


    //Retorna un DataTable que contiene los atributos de nombre y cédula de los clientes.
    public List<ClientesEnt> ObtenerClientes()
    {
        listClientes = this.ctrlClientes.ObtenerClientes();
        return listClientes;
    }


    //Retorna todos los atributos de modulo
    public AtributosCtrl SolicitarEstadoAtributos()
    {
        return this.atributos;
    }

//*********************************
    //Realiza la accion correspondiente al estado en el que se encuentra
    //segun el primer parametro, si es true modifica de lo contario inserta.
    //Retorna true si la operacion realizada fue exitosa y false en caso contrario
    public bool AccionesAceptar(bool modificando, int id, string nombre, DateTime fechaInicial, int prioridad, int lider, 
                                int cliente, string estado, int complejidad, int gtiAlbrecht, int gtiGarmus, 
                                double productividadHistorica, int costoXHora, int duracionReal, string descripcion, double horasPersonaMes)
    {
        bool resultado;

        if(modificando) {
            resultado =  bdProyectos.ActualizarProyecto( this.CrearObjetoProyecto (nombre, fechaInicial, prioridad, lider, cliente, estado, complejidad, gtiAlbrecht, gtiGarmus, productividadHistorica, costoXHora, duracionReal, descripcion, horasPersonaMes) , id);
            resultado = ModificarIteraciones();       
            ctrlEmpleados.ModificarRecursosHumanos(entProyectos.Id, (List<EmpleadosEnt>)listEmpleadosAsignados);
        }
        else {
            resultado = bdProyectos.InsertarProyecto( this.CrearObjetoProyecto (nombre, fechaInicial, prioridad, lider, cliente, estado, complejidad, gtiAlbrecht, gtiGarmus, productividadHistorica, costoXHora, duracionReal, descripcion, horasPersonaMes));
            ctrlEmpleados.ModificarRecursosHumanos(bdProyectos.ObtenerUltimoId(), (List<EmpleadosEnt>)listEmpleadosAsignados);
            ((List<EmpleadosEnt>)listEmpleadosPosibles).Clear();
        }

        return resultado;
    }


    public List<IteracionEnt> CargarIteraciones()
    {
        listIteraciones.Clear();
        
        listIteraciones = bdEstructuracion.ConsultarIteraciones(entProyectos.Id );
        
        return listIteraciones;
    }


    public Object CargarEmpleadosDisponibles()
    {
        ((List<EmpleadosEnt>)listEmpleadosPosibles).Clear();
        listEmpleadosPosibles = ctrlEmpleados.ConsultarEmpleadosDisponibles(entProyectos.Id);
      
        return listEmpleadosPosibles;
    }


    public Object CargarEmpleadosAsignados()
    {
        ((List<EmpleadosEnt>)listEmpleadosAsignados).Clear();
        listEmpleadosAsignados = ctrlEmpleados.ConsultarEmpleadosAsignados( entProyectos.Id);
        
        return listEmpleadosAsignados;
    }


    public double CalcularProductividadHistorica(int complejidad ) {
        return bdProyectos.CalcularProductividadHistorica( complejidad );
    }


    public void LimpiarListaRecursosHumanos() {
        ((List<EmpleadosEnt>)listEmpleadosPosibles).Clear();
        ((List<EmpleadosEnt>)listEmpleadosAsignados).Clear();
    }


    public void LimpiarListaIteraciones()
    {
        listIteraciones.Clear();
    }


    public IteracionEnt CargarIteracion(int idIteracion) {
        int i = 0;
        while ( listIteraciones[i].Id != idIteracion)
            i++;
        
        return listIteraciones[i];
    }


    public void EmpleadoAsignadoADisponible (int cedulaEmpleado) {
        EmpleadosEnt empleadoATransferir;
        int i = 0;
        while ( ((List<EmpleadosEnt>)listEmpleadosAsignados)[i].Cedula != cedulaEmpleado )
            i++;

        empleadoATransferir = ((List<EmpleadosEnt>)listEmpleadosAsignados)[i];
        ((List<EmpleadosEnt>)listEmpleadosPosibles).Add( empleadoATransferir );
        ((List<EmpleadosEnt>)listEmpleadosAsignados).Remove( empleadoATransferir );
    }


    public void EmpleadoDisponibleAAsignado (int cedulaEmpleado) {
        EmpleadosEnt empleadoATransferir;
        int i = 0;
        while ( ((List<EmpleadosEnt>)listEmpleadosPosibles)[i].Cedula != cedulaEmpleado )
            i++;

        empleadoATransferir = ((List<EmpleadosEnt>)listEmpleadosPosibles)[i];
        ((List<EmpleadosEnt>)listEmpleadosAsignados).Add( empleadoATransferir );
        ((List<EmpleadosEnt>)listEmpleadosPosibles).Remove( empleadoATransferir );
    }

    public object GetListaEmpleadosAsignados ( ) {
        return listEmpleadosAsignados;
    }


    public object GetListaEmpleadosPosibles ( ) {
        return listEmpleadosPosibles;
    }


    public bool ModificarRecursosHumanos () {
        return ctrlEmpleados.ModificarRecursosHumanos( entProyectos.Id, ((List<EmpleadosEnt>)listEmpleadosAsignados) );
    }
    

    public IteracionEnt ReCalcularEstimaciones (int idIteracion, double PFSAGarmus, double PFSAAlbrecht, double horasPersonaMes) {
        int i = 0;
        if (idIteracion != -1)
        {
            while ( listIteraciones[i].Id != idIteracion)
                i++;
            
            listIteraciones[i].PfsaAlbrecht = PFSAAlbrecht;
            listIteraciones[i].PfsaGarmus = PFSAGarmus;
            listIteraciones[i].PfAlbrecht = GetPFAjustados( entProyectos.GtiAlbrecht, listIteraciones[i].PfsaAlbrecht);
            listIteraciones[i].PfGarmus = GetPFAjustados( entProyectos.GtiGarmus, listIteraciones[i].PfsaGarmus);
            listIteraciones[i].CasperJonesAlb = GetCasperJones(listIteraciones[i].PfAlbrecht, horasPersonaMes);
            listIteraciones[i].CasperJonesGar = GetCasperJones(listIteraciones[i].PfGarmus, horasPersonaMes);
            listIteraciones[i].IsbgAlb = GetISBG(listIteraciones[i].PfAlbrecht);
            listIteraciones[i].IsbgGar = GetISBG(listIteraciones[i].PfGarmus); ;
            listIteraciones[i].Albrecht = GetEstimacionTiempo(listIteraciones[i].PfAlbrecht, entProyectos.ProductividadHistorica);
            listIteraciones[i].Garmus = GetEstimacionTiempo(listIteraciones[i].PfGarmus, entProyectos.ProductividadHistorica);  
            listIteraciones[i].ProductividadReal = 0;//PENDIENTE HASTA REGISTRO DE HORAS
        
            return listIteraciones[i];
        }

        else {
            IteracionEnt vacio = new IteracionEnt();
            return (vacio);
        }
    }


    public double GetFactorAjuste(int GTI) {
        return ((GTI*0.01)+0.65);
    }
    

    public double GetPFAjustados (int GTI, double PFSA) {
        return ((this.GetFactorAjuste(GTI))*PFSA);
    }


    public double GetCasperJones(double PF, double horasPersonaMes)
    {
        return ((PF / 150) * Math.Pow(PF, 0.4) * horasPersonaMes);
    }

    public double GetISBG(double PF)
    {
        return ((11.79) * Math.Pow(PF, 0.898));
    }

    public double GetEstimacionTiempo(double PF, double ProdHist )
    {
        return (PF*ProdHist);
    }

    public double GetProductividadReal ()
    {
        return 0;
    }


    public ProyectoEnt CrearObjetoProyecto ( int id, string nombre, DateTime fechaInicial, int prioridad, int lider, int cliente, string estado,
                                             int complejidad, int gtiAlbrecht, int gtiGarmus, double productividadHistorica, int costoXHora, int duracionReal, string descripcion, double horasPersonaMes) {
        ProyectoEnt encapsulado;
        encapsulado = new ProyectoEnt(id, nombre, fechaInicial, prioridad, lider, cliente, estado,
                             complejidad, gtiAlbrecht, gtiGarmus, productividadHistorica, costoXHora, duracionReal, descripcion, horasPersonaMes);
        return encapsulado;
    }


    public ProyectoEnt CrearObjetoProyecto( string nombre, DateTime fechaInicial, int prioridad, int lider, int cliente, string estado,
                                           int complejidad, int gtiAlbrecht, int gtiGarmus, double productividadHistorica, int costoXHora, int duracionReal, string descripcion, double horasPersonaMes)
    {
        ProyectoEnt encapsulado;
        encapsulado = new ProyectoEnt (nombre, fechaInicial, prioridad, lider, cliente, estado,
                             complejidad, gtiAlbrecht, gtiGarmus, productividadHistorica, costoXHora, duracionReal, descripcion, horasPersonaMes);
        return encapsulado;
    }

    public DataTable ObtenerComplejidad()
    {
        return this.bdProyectos.ObtenerComplejidad();
    }


    public DataTable ObtenerEstados()
    {
        return this.bdProyectos.ObtenerEstados();
    }

    public int ObtenerUltimoId()
    {
        return bdProyectos.ObtenerUltimoId();
    }


    public void ModificarIteracionTemp(string id, string pfsaAlbrecht, string pfsaGarmus, string horasPersonaMes)
    {
        int Id= Convert.ToInt32(id);
        double PfsaAlbrecht = (pfsaAlbrecht!="")?Convert.ToDouble(pfsaAlbrecht):0;
        double PfsaGarmus = (pfsaGarmus!="")?Convert.ToDouble(pfsaGarmus):0;
        double HorasPersonaMes = (horasPersonaMes != "") ? Convert.ToDouble(horasPersonaMes) : 0;

        ReCalcularEstimaciones(Id, PfsaGarmus, PfsaAlbrecht, HorasPersonaMes);

    }


    public bool ModificarIteraciones()
    {
        return bdEstructuracion.ActualizarIteraciones(listIteraciones) ;
    }



    //**************************************************Carga Proyectos Limitada por Cuenta**********************
    public List<ProyectoEnt> CargarProyectos(int cuenta)
    {
        int cedula = bdProyectos.ObtenerEmpleadoDeCuenta(cuenta);
        return this.bdProyectos.RecuperarProyectos(cedula);
    }

    public DataTable ActualizarGrid(int cuenta)
    {
        int cedula = bdProyectos.ObtenerEmpleadoDeCuenta(cuenta);
        return this.bdProyectos.ConsultarProyectos(cedula);
    }


}
